#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <semaphore.h>
#include "Gomoku.h"
#include "mouse_input.h"
#include <math.h>


#define server_port 8888
#define server_ip "192.168.13.154"

typedef struct Data{
    int socket_fd;
    char **board;
}data_t;

sem_t sem;
mouse_event_t mouse_data;

void *listen_event(void *arg){
    listen_mouse((mouse_event_t *)arg);
}


void *send_to_service(void* argv){

    data_t data = *(data_t *)argv;
    int client_fd = data.socket_fd;
    char **board = data.board;
    char buf[1024];
    int game=1;

    printf("请点击1,1坐标\n");
    printf_Board(board);
    sem_wait(&sem);
    
    printf("请点击15,15坐标\n");
    printf_Board(board);

    sem_wait(&sem);
    float block_distance_row=-(mouse_data.borad_size_y/14.0), block_distance_col=mouse_data.borad_size_x/14.0;

    
    while(1){
        if (game)
        {
            printf("游戏开始，你是白子，请选择你的落子位置\n");
            game=0;
            printf_Board(board);
        }
        
        sem_wait(&sem);
        memset(buf, 0, sizeof(buf));
        //判断鼠标点击的坐标是否在棋盘内
        int row; int col;
        if(mouse_data.x<=-10 && mouse_data.x>=(mouse_data.borad_size_x+10)||mouse_data.y>=10||mouse_data.y<=(mouse_data.borad_size_y-10)){
            printf("点击坐标超出棋盘范围\n");
        }else{

            //先求出可能有效的坐标
            row=round((mouse_data.y)/block_distance_row);
            col=round(mouse_data.x/block_distance_col);

            //倒回去判断这个可能的坐标是否符合误差+-10
            if ((row*block_distance_row-10)<= mouse_data.y && mouse_data.y<=(row*block_distance_row+10) && (col*block_distance_col-10)<= mouse_data.x && mouse_data.x<=(col*block_distance_col+10))
            {
                
                //判断坐标是否合规
                if(row<=0&&row>=-14&&col>=0&&col<=14){
                    sprintf(buf, "%d,%d\n", -(row-1), col+1);
                    write(client_fd, buf, strlen(buf));
                    printf("buf:%s\n",buf);
                    Draw_Board(board, -(row-1), col+1,2);
                    if(Judge_wins(board, -(row-1), col+1, 2)){
                        printf("玩家2获胜\n");
                        printf_Board(board);
                        exit(EXIT_FAILURE);
                    }
                }else{
                    printf("点击坐标超出棋盘范围\n");
                }
            }else{
                printf("点击坐标超出棋盘范围\n");
            }
            
        }

        printf_Board(board);
    }
}

void *recv_to_service(void* argv){
    char *recv_buf=malloc(sizeof(char)*1024);
    data_t data = *(data_t *)argv;
    int client_fd = data.socket_fd;
    char **board = data.board;

    while (1)
    {

        memset(recv_buf, 0, sizeof(recv_buf));
        if(recv(client_fd, recv_buf, sizeof(recv_buf), 0)==-1){
            perror("recv error");
            exit(1);
        }
        printf("recv_buf:%s\n", recv_buf);
        int row=0, col=0, flag=1;
        for (int i = 0; i < strlen(recv_buf); i++)
        {   
            if (recv_buf[i]=='\n')
            {
                break;
            }
            if( recv_buf[i]==','){
                flag=0;
                continue;
            }
            if (flag)
            {
                row=row*10+recv_buf[i]-'0';
            }else
            {
                col=col*10+recv_buf[i]-'0';
            }
        }
        printf("row:%d, col:%d\n", row, col);
        Draw_Board(board, row, col,1);
        if(Judge_wins(board, row, col, 1)){
            printf("玩家1获胜\n");
            printf_Board(board);
            exit(EXIT_FAILURE);
        }
        printf_Board(board);
        memset(recv_buf, 0, strlen(recv_buf));
    
    }

}




int main(int argc, char const *argv[])
{
    int client_socket= socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr,client_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    memset(&client_addr, 0, sizeof(client_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    server_addr.sin_addr.s_addr = inet_addr(server_ip);



    if(connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))==-1){
        perror("connect error");
        exit(1);
    }
    printf("连接成功\n");
    char **board=Board_Init();
    data_t data={client_socket,board};
    printf_Board(board);

    //创建线程
    pthread_t read_tid,write_tid;
    pthread_create(&read_tid, NULL, recv_to_service, (void *)&data);
    pthread_create(&write_tid, NULL, send_to_service, (void *)&data);

    //开启鼠标监听线程
    pthread_t mouse_tid;

    mouse_data.sem=&sem;

    pthread_create(&mouse_tid, NULL, listen_event, (void *)&mouse_data);


    pthread_join(read_tid, NULL);
    pthread_join(write_tid, NULL);
    pthread_join(mouse_tid, NULL);

    free(board);
    close(client_socket);



    return 0;
}
